﻿using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.IO;
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.Linq;

namespace NewsWebsite.Controllers
{
    [Route("api/netDiskStorage")]
    [ApiController]
    public class NetDiskStorageController : ControllerBase
    {

        private readonly IWebHostEnvironment _env;

        public NetDiskStorageController(IWebHostEnvironment env)
        {
            _env = env;
        }

        private string GetStoragePath()
        {
            return Path.Combine(_env.WebRootPath, "NetDiskStorage");
        }

        // 1. 新增文件 (上传)
        [HttpPost("upload")]
        public async Task<IActionResult> UploadFile(IFormFile file)
        {
            if (file == null || file.Length == 0)
            {
                return BadRequest(new { code = 400, msg = "文件不能为空" });
            }

            try
            {
                // 确保文件夹存在
                string folderPath = GetStoragePath();
                if (!Directory.Exists(folderPath))
                {
                    Directory.CreateDirectory(folderPath);
                }

                // 保存文件
                string filePath = Path.Combine(folderPath, file.FileName);
                using (var stream = new FileStream(filePath, FileMode.Create))
                {
                    await file.CopyToAsync(stream);
                }

                return Ok(new { code = 200, msg = "文件上传成功", fileName = file.FileName });
            }
            catch (Exception ex)
            {
                return StatusCode(500, new { code = 500, msg = "文件上传失败", error = ex.Message });
            }
        }

        // 2. 查询文件和目录列表
        [HttpGet("list")]
        public IActionResult GetFileList()
        {
            try
            {
                string folderPath = GetStoragePath();
                if (!Directory.Exists(folderPath))
                {
                    return Ok(new { code = 0, msg = "文件夹为空", files = new string[0] });
                }
                // 获取目录中的所有子目录（文件夹）
                string[] subDirectories = Directory.GetDirectories(folderPath);
                var DirectoriesNames = Array.ConvertAll(subDirectories, Path.GetFileName);
                ///获取文件目录
                var files = Directory.GetFiles(folderPath);
                var fileNames = Array.ConvertAll(files, Path.GetFileName);
              List<ResultFiles> resultFiles = new List<ResultFiles>();
                for (int i = 0; i < DirectoriesNames.Length; i++)
                {
                    
                    ResultFiles item = new ResultFiles { FilesId= Guid.NewGuid().ToString(), FileName = DirectoriesNames[i],FileType=0 };
                    resultFiles.Add(item);
                }
                for (int i = 0; i < fileNames.Length; i++)
                {

                    ResultFiles item = new ResultFiles { FilesId = Guid.NewGuid().ToString(), FileName = fileNames[i], FileType = 1 };
                    resultFiles.Add(item);
                }
                //ResultFiles resultFiles = new ResultFiles {Directories= DirectoriesNames, Files= fileNames };
                return Ok(new { code=0,msg="获取文件列表成功",data=resultFiles});
            }
            catch (Exception ex)
            {
                return StatusCode(500, new { code = 500, msg = "获取文件列表失败", error = ex.Message });
            }
        }

        public class ResultFiles {
            public string? FilesId { get; set; }

            public string?  FileName { get; set; }
            /// <summary>
            /// 0文件夹 1文件
            /// </summary>
            public int? FileType { get; set; }
        }


        // 3. 读取指定文件内容
        [HttpGet("read/{fileName}")]
        public IActionResult ReadFile(string fileName)
        {
            try
            {
                string filePath = Path.Combine(GetStoragePath(), fileName);
                if (!System.IO.File.Exists(filePath))
                {
                    return NotFound(new { code = 404, msg = "文件不存在" });
                }

                var fileContent = System.IO.File.ReadAllText(filePath);
                return Ok(new { code = 200, msg = "文件读取成功", content = fileContent });
            }
            catch (Exception ex)
            {
                return StatusCode(500, new { code = 500, msg = "读取文件失败", error = ex.Message });
            }
        }

        // 4. 修改文件内容
        [HttpPut("update/{fileName}")]
        public IActionResult UpdateFile(string fileName, [FromBody] string newContent)
        {
            try
            {
                string filePath = Path.Combine(GetStoragePath(), fileName);
                if (!System.IO.File.Exists(filePath))
                {
                    return NotFound(new { code = 404, msg = "文件不存在" });
                }

                System.IO.File.WriteAllText(filePath, newContent);
                return Ok(new { code = 200, msg = "文件更新成功" });
            }
            catch (Exception ex)
            {
                return StatusCode(500, new { code = 500, msg = "文件更新失败", error = ex.Message });
            }
        }

        // 5. 删除指定文件
        [HttpDelete("delete/{fileName}")]
        public IActionResult DeleteFile(string fileName)
        {
            try
            {
                string filePath = Path.Combine(GetStoragePath(), fileName);
                if (!System.IO.File.Exists(filePath))
                {
                    return NotFound(new { code = 404, msg = "文件不存在" });
                }

                System.IO.File.Delete(filePath);
                return Ok(new { code = 200, msg = "文件删除成功" });
            }
            catch (Exception ex)
            {
                return StatusCode(500, new { code = 500, msg = "文件删除失败", error = ex.Message });
            }
        }

        /// <summary>
        //        /// IFormFile file: 当前上传的文件块。
        //        int chunkIndex: 当前分块的索引，用于标识文件块的顺序。
        //string fileHash: 文件的唯一标识符，用于区分不同文件（比如 MD5 或 SHA-256 哈希值）。
        //int totalChunks: 文件的总块数，用于检查是否所有块已经上传完成。
        /// </summary>
        /// <param name="file"></param>
        /// <param name="chunkIndex"></param>
        /// <param name="fileHash"></param>
        /// <param name="totalChunks"></param>
        /// <returns></returns>
        [HttpPost("resumeUpload")]
        public async Task<IActionResult> ResumeUpload([FromForm]FileChunkDto chunkDto)
        {
            // 验证输入
            if (chunkDto.File == null || chunkDto.File.Length == 0)
            {
                return BadRequest(new { status = "File is required." });
            }

            // 创建文件夹保存分块
            var uploadPath = Path.Combine(GetStoragePath(), chunkDto.FileHash); // 以文件哈希作为文件夹名称
            if (!Directory.Exists(uploadPath))
            {
                Directory.CreateDirectory(uploadPath);
            }

            // 保存分块到临时目录
            var chunkPath = Path.Combine(uploadPath, $"chunk-{chunkDto.ChunkIndex}");
            using (var stream = new FileStream(chunkPath, FileMode.Create))
            {
                await chunkDto.File.CopyToAsync(stream);
            }

            // 检查是否所有块上传完成
            if (Directory.GetFiles(uploadPath).Length == chunkDto.TotalChunks)
            {
                var finalFilePath = Path.Combine(GetStoragePath(), chunkDto.FileName);
                using (var finalStream = new FileStream(finalFilePath, FileMode.Create))
                {
                    for (int i = 0; i < chunkDto.TotalChunks; i++)
                    {
                        var chunkFilePath = Path.Combine(uploadPath, $"chunk-{i}");
                        using (var chunkStream = new FileStream(chunkFilePath, FileMode.Open))
                        {
                            await chunkStream.CopyToAsync(finalStream);
                        }
                        System.IO.File.Delete(chunkFilePath); // 删除分块文件
                    }
                }
                Directory.Delete(uploadPath); // 删除临时目录
            }

            return Ok(new { code = 0, msg= $"总块数{chunkDto.TotalChunks}，当前分块{chunkDto.ChunkIndex}", TotalChunks=chunkDto.TotalChunks, ChunkIndex =chunkDto.ChunkIndex+1});
        }
        public class FileChunkDto
        {
            public IFormFile File { get; set; }       // 文件块
            public int ChunkIndex { get; set; }       // 分块索引
            public string FileHash { get; set; }      // 文件哈希
            public int TotalChunks { get; set; }      // 总分块数
            public string FileName { get; set; }      // 文件名
        }



    }
}
